using System;

namespace Crusades.Helpers {
  public class Bezier {
    private readonly Vector[] P;
    readonly Func<Vector, Vector, double, Vector> lerp = (A, B, t) => (1 - t) * A + t * B;

    public Bezier(Vector[] controlPoints) {
      P = controlPoints;
    }

    public Bezier(){
      
    }

    public Vector[] ControlPoints {
      get { return P; }
    }

    public string ToData() {
      const string dataMask = "Data=\"M{0},{1} C{2},{3} {4},{5} {6},{7}\"";
      return string.Format(dataMask, P[0].X, P[0].Y, P[1].X, P[1].Y, P[2].X, P[2].Y, P[3].X, P[3].Y);
    }

    public override string ToString() {
      const string mask = "p0={0} p1={1} p2={2} p3={3}";
      return string.Format(mask, P[0], P[1], P[2], P[3]);
    }

    public Vector LinearInterpolation(Vector A, Vector B, double t){
      return lerp(A, B, t);
    }

    public Bezier SplitTo(double t) {
      Vector p10 = lerp(P[0], P[1], t);
      Vector p20 = lerp(P[1], P[2], t);
      Vector p30 = lerp(P[2], P[3], t);

      Vector p21 = lerp(p10, p20, t);
      Vector p22 = lerp(p20, p30, t);

      Vector p32 = lerp(p21, p22, t);


      return new Bezier(new[]{P[0], p10, p21, p32});

    }
    public Vector this[int index]{
      get{return P[index];}
    }
    public override bool Equals(object obj){
      if(ReferenceEquals(obj,null)){return false;}
      Bezier other = (Bezier) obj;
      if(ControlPoints.Length != other.ControlPoints.Length){return false;}
      for (int i = 0; i < ControlPoints.Length; i++){
        if(!ControlPoints[i].Equals(other.ControlPoints[i],.01)){
          return false;
        }
      }
      return true;
    }

    public override int GetHashCode() {
      return P!=null ? P.GetHashCode() : 0;
    }

  }
}